import { defineStore } from 'pinia';
import * as Cesium from 'cesium';
import { useScaleStore } from "@/stores/scaleStore";
// 节流函数
function throttle(fn, wait) {
  let time = Date.now();
  return function (...args) {
    if ((time + wait - Date.now()) < 0) {
      fn.apply(this, args);
      time = Date.now();
    }
  }
}

export const useData2DStore = defineStore('data2D', {
  state: () => ({
    viewer: null,
    data: [],
    header: {},
    minDataValue: 0,
    maxDataValue: 2,
    colors: [
      "#0D4D4B",
      "#35A69C",
      "#64E9EE",
      "#FFCC00",
    ],
    isGradient: true,
    primitive: null,
    handler: null,
    isVisible: false,
    loading: false,
    currentDataId: null,
    isSceneReady: false, // 新增场景就绪状态
  }),
  actions: {
    setViewer(viewer) {
      this.viewer = viewer;
      // 监听场景就绪事件
      this.viewer.scene.postRender.addEventListener(() => {
        if (!this.isSceneReady) {
          this.isSceneReady = true;
        }
      });
    },
    setData(data) {
      this.data = data;
    },
    setHeader(header) {
      this.header = header;
    },
    setMinDataValue(minDataValue) {
      this.minDataValue = minDataValue;
    },
    setMaxDataValue(maxDataValue) {
      this.maxDataValue = maxDataValue;
    },
    setColors(colors) {
      this.colors = colors;
    },
    setIsGradient(isGradient) {
      this.isGradient = isGradient;
    },
    setIsVisible(isVisible) {
      this.isVisible = isVisible;
    },

    // 清理现有资源
    cleanup() {
      if (this.primitive) {
        this.viewer.scene.primitives.remove(this.primitive);
        this.primitive = null;
      }
      if (this.handler) {
        this.handler.destroy();
        this.handler = null;
      }
      this.loading = false;
    },

    // 分批创建几何实例
    createGeometryInstancesBatch(data, header, cesiumColors) {
      const instances = [];
      const batchSize = 5000; // 每批处理5000个点
      const totalPoints = header.numberPoints;
      
      for (let batchStart = 0; batchStart < totalPoints; batchStart += batchSize) {
        const batchEnd = Math.min(batchStart + batchSize, totalPoints);
        
        for (let i = batchStart; i < batchEnd; i++) {
          if (this.data[i] === "NaN" || this.data[i] == null) continue;

          const value = parseFloat(this.data[i]);
          const lon = header.lo1 + (i % header.nx) * header.dx;
          const lat = header.la1 + Math.floor(i / header.nx) * header.dy;
          const color = this.temperatureToColor(
            value, 
            this.isGradient, 
            cesiumColors, 
            this.minDataValue, 
            this.maxDataValue
          );
          
          instances.push(
            new Cesium.GeometryInstance({
              geometry: new Cesium.RectangleGeometry({
                rectangle: Cesium.Rectangle.fromDegrees(lon, lat, lon + header.dx, lat + header.dy),
                vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
              }),
              id: value, // 直接存储数值而不是数组引用
              attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(color),
              },
            })
          );
        }
      }
      
      return instances;
    },

    // 异步加载数据
    async loadTestData(dataId) {
      // 如果正在加载相同数据，直接返回
      if (this.loading && this.currentDataId === dataId) return;
      
      // 确保场景已就绪
      if (!this.isSceneReady) {
        await new Promise(resolve => {
          const checkReady = () => {
            if (this.isSceneReady) {
              resolve();
            } else {
              requestAnimationFrame(checkReady);
            }
          };
          checkReady();
        });
      }
      
      // 清理现有资源
      this.cleanup();
      
      // 设置加载状态
      this.loading = true;
      this.currentDataId = dataId;
      
      try {
        // 解析header参数
        this.header.la1 = parseFloat(this.header.la1);
        this.header.la2 = parseFloat(this.header.la2);
        this.header.lo1 = parseFloat(this.header.lo1);
        this.header.lo2 = parseFloat(this.header.lo2);
        this.header.dx = parseFloat(this.header.dx);
        this.header.dy = parseFloat(this.header.dy);

        const cesiumColors = this.colors.map(color =>
          Cesium.Color.fromCssColorString(color)
        );

        // 分批创建几何实例
        const instances = this.createGeometryInstancesBatch(this.data, this.header, cesiumColors);

        if (instances.length > 0) {
          // 使用PrimitiveCollection而不是直接添加Primitive
          const primitiveCollection = new Cesium.PrimitiveCollection();
          
          // 每10000个实例创建一个Primitive
          const primitiveSize = 10000;
          for (let i = 0; i < instances.length; i += primitiveSize) {
            const batchInstances = instances.slice(i, i + primitiveSize);
            
            const primitive = new Cesium.Primitive({
              geometryInstances: batchInstances,
              appearance: new Cesium.PerInstanceColorAppearance({
                flat: true,
                translucent: false,
              }),
              asynchronous: false, // 禁用异步处理
            });
            
            primitiveCollection.add(primitive);
          }
          
          this.primitive = this.viewer.scene.primitives.add(primitiveCollection);
        }

        this.addMouseMoveHandler();
        this.isVisible = true;
      } catch (error) {
        console.error("加载数据失败:", error);
        // 在错误情况下也确保清理资源
        this.cleanup();
      } finally {
        this.loading = false;
      }
    },

    // 显示图层
    show() {
      if (!this.isVisible) {
        this.isVisible = true;
        if (!this.primitive && this.data.length > 0) {
          this.loadTestData('current');
        }
      }
    },

    // 隐藏图层
    hide() {
      if (this.isVisible) {
        this.isVisible = false;
        this.cleanup();
      }
    },

    // 切换显隐状态
    toggleVisibility() {
      if (this.isVisible) {
        this.hide();
      } else {
        this.show();
      }
    },

    generateBreaks(min, max, count) {
      const step = (max - min) / count;
      let breaks = [];
      for (let i = 0; i <= count; i++) {
        breaks.push(min + i * step);
      }
      return breaks;
    },

    addMouseMoveHandler() {
      if (!this.viewer || !this.primitive) return;
    
      if (this.handler) this.handler.destroy();
      this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    
      this.handler.setInputAction(throttle((movement) => {
        try {
          const scaleStore = useScaleStore();
          const scale = scaleStore.currentScale || 1;
    
          // 反向计算：鼠标坐标除以缩放比例
          const adjustedX = movement.endPosition.x / scale;
          const adjustedY = movement.endPosition.y / scale;
  
          // console.log("原始坐标:", { x: movement.endPosition.x, y: movement.endPosition.y });
          // console.log("调整后坐标:", { x: finalX, y: finalY, scale });
    
          const adjustedPosition = new Cesium.Cartesian2(adjustedX, adjustedY);
    
          // 使用调整后的坐标进行拾取
          const ray = this.viewer.camera.getPickRay(adjustedPosition);
          if (!ray) return;
    
          const cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
          if (!cartesian) return;
    
          const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
          const lon = Cesium.Math.toDegrees(cartographic.longitude);
          const lat = Cesium.Math.toDegrees(cartographic.latitude);
    
          const pick = this.viewer.scene.pick(adjustedPosition);
          let value = Cesium.defined(pick) ? pick.id : null;
    
          this.emitTemplatureOrSalt(value == null ? null : {
            lon: lon.toFixed(4),
            lat: lat.toFixed(4),
            value: Number(value).toFixed(4),
            name: ""
          });
        } catch (error) {
          console.error("鼠标移动处理错误:", error);
        }
      }, 50), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    },

    emitTemplatureOrSalt(data) {
      const event = new CustomEvent('templatureOrSalt', { detail: data });
      window.dispatchEvent(event);
    },

    temperatureToColor(currentTemp, mode, colorMap, minVal, maxVal) {
      currentTemp = Math.min(Math.max(currentTemp, minVal), maxVal);

      if (!mode) {
        const segmentSize = (maxVal - minVal) / (colorMap.length - 1);
        let segmentIndex = Math.floor((currentTemp - minVal) / segmentSize);
        return colorMap[Math.min(segmentIndex, colorMap.length - 1)];
      } else if (mode) {
        const ratio = (currentTemp - minVal) / (maxVal - minVal);
        const index = Math.floor(ratio * (colorMap.length - 1));
        if (index >= colorMap.length - 1) return colorMap[colorMap.length - 1];
        const t = ratio * (colorMap.length - 1) - index;
        return Cesium.Color.lerp(colorMap[index], colorMap[index + 1], t, new Cesium.Color());
      }
    }
  },
});